//
//  MGOperation.m
//  Mango
//
//  Created by 胡超 on 2021/3/1.
//  Copyright © 2021年 胡超., ltd. All rights reserved.
//

#import "MGOperation.h"

@interface MGOperation () {
    MGOperationExecution _execution;
    BOOL _inMainThread;
    NSRecursiveLock *_lock;
}
@property (readwrite, getter=isStarted) BOOL started;

@end

@implementation MGOperation
@synthesize finished = _finished;

+ (instancetype)operationWithExecution:(MGOperationExecution)execution {
    MGOperation *operation = [[self alloc] initWithExecution:execution inMainThread:NO];
    return operation;
}

+ (instancetype)operationInMainThreadWithExecution:(MGOperationExecution)execution {
    MGOperation *operation = [[self alloc] initWithExecution:execution inMainThread:YES];
    return operation;
}

- (instancetype)initWithExecution:(MGOperationExecution)execution inMainThread:(BOOL)inMainThread {
    if (self = [super init]) {
        _execution = execution;
        _inMainThread = inMainThread;
        _lock = [[NSRecursiveLock alloc] init];
    }
    return self;
}

- (void)setFinished:(BOOL)finished {
    [_lock lock];
    if (_finished != finished) {
        [self willChangeValueForKey:@"isFinished"];
        _finished = finished;
        [self didChangeValueForKey:@"isFinished"];
    }
    [_lock unlock];
}

- (BOOL)isFinished {
    [_lock lock];
    BOOL finished = _finished;
    [_lock unlock];
    return finished;
}

- (void)start {
    self.started = YES;
    if (self.isCancelled) {
        self.finished = YES;
        return;
    }
    
    if (_inMainThread) {
        dispatch_async(dispatch_get_main_queue(), ^{
            _execution(self);
        });
    } else {
        _execution(self);
    }
}

- (void)cancel {
    [_lock lock];
    [super cancel];
    if (self.started) {
        self.finished = YES;
    }
    [_lock unlock];
}

@end
